﻿using System.Collections;
using Infrastructure.Extensions;
using Infrastructure.Helper;
using Infrastructure.Model;
using Infrastructure.Model.ApiResult;
using Infrastructure.Model.UserAuth;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Newtonsoft.Json;

namespace Infrastructure.Centers
{

    /// <summary>
    /// 服务调用客户端：封装基于HTTP的微服务调用，支持传递追踪信息和用户身份令牌
    /// </summary>
    public class Service
    {
        private readonly string serviceName; // 目标服务名称（用于日志/监控）
        private readonly string url;         // 目标服务基础地址（如：192.168.1.10:8080）
        private readonly IHttpContextAccessor _httpContextAccessor; // HTTP上下文访问器

        /// <summary>
        /// 构造函数（注意：直接从全局 ServiceProvider 获取依赖，可能有生命周期问题）
        /// </summary>
        /// <param name="serviceName">服务标识名称</param>
        /// <param name="url">服务基础地址（不带协议）</param>
        public Service(string serviceName, string url)
        {
            // 从全局服务提供者获取上下文访问器（风险点：可能获取到错误生命周期的实例）
            _httpContextAccessor = App.ServiceProvider.GetRequiredService<IHttpContextAccessor>();
            this.serviceName = serviceName;
            this.url = url;
        }

        #region HTTP GET 方法组
        //----------------------------------------------------------

        /// <summary>
        /// 发起GET请求（返回原始ApiResult）
        /// </summary>
        /// <param name="methodName">接口路径（如："api/user"）</param>
        /// <param name="queryParams">查询参数</param>
        /// <returns>包含原始数据的响应结果</returns>
        public ApiResult Get(string methodName, Hashtable queryParams = null)
        {
            if (string.IsNullOrEmpty(methodName))
                throw new Exception("功能名字不可为空");

            // 清理路径中的斜杠并构建完整URL
            return new RestfulHelper(GetHeader()).Get(
                BuildUrl(methodName),
                queryParams
            );
        }

        /// <summary>
        /// 发起GET请求（返回泛型结果）
        /// </summary>
        /// <typeparam name="T">预期返回的数据类型</typeparam>
        /// <param name="methodName">接口路径</param>
        /// <param name="queryParams">查询参数</param>
        /// <returns>包含反序列化对象的响应结果</returns>
        public ApiResult<T> Get<T>(string methodName, Hashtable queryParams = null) where T : class
        {
            ApiResult apiResult = Get(methodName, queryParams);

            // 处理空响应数据
            if (string.IsNullOrWhiteSpace(apiResult.Data?.ToString()))
                return new ApiResult<T>(apiResult.Code, apiResult.Msg, null);

            try
            {
                // 尝试反序列化JSON数据
                return new ApiResult<T>(
                    apiResult.Code,
                    apiResult.Msg,
                    JsonConvert.DeserializeObject<T>(apiResult.Data?.ToString())
                );
            }
            catch (Exception)
            {
                return ApiResult<T>.Error("Failed to parse data");
            }
        }

        #endregion

        #region HTTP POST 方法组
        //----------------------------------------------------------

        /// <summary>
        /// 发起无参POST请求
        /// </summary>
        public ApiResult Post(string methodName)
        {
            ValidateMethodName(methodName);
            return new RestfulHelper(GetHeader()).Post(BuildUrl(methodName));
        }

        /// <summary>
        /// 发起带请求体的POST请求
        /// </summary>
        public ApiResult Post(string methodName, object body)
        {
            ValidateMethodName(methodName);
            return new RestfulHelper(GetHeader()).Post(BuildUrl(methodName), body);
        }

        /// <summary>
        /// 发起带查询参数的POST请求
        /// </summary>
        public ApiResult Post(string methodName, Hashtable queryParams)
        {
            ValidateMethodName(methodName);
            return new RestfulHelper(GetHeader()).Post(BuildUrl(methodName), queryParams);
        }

        /// <summary>
        /// 发起完整POST请求（带查询参数和请求体）
        /// </summary>
        public ApiResult Post(string methodName, Hashtable queryParams, object body)
        {
            ValidateMethodName(methodName);
            return new RestfulHelper(GetHeader()).Post(BuildUrl(methodName), queryParams, body);
        }

        /// <summary>
        /// 发起POST请求并返回泛型结果
        /// </summary>
        public ApiResult<T> Post<T>(string methodName, Hashtable queryParams = null, object body = null) where T : class
        {
            ApiResult apiResult = Post(methodName, queryParams, body);

            if (string.IsNullOrWhiteSpace(apiResult.Data?.ToString()))
                return new ApiResult<T>(apiResult.Code, apiResult.Msg, null);

            try
            {
                return new ApiResult<T>(
                    apiResult.Code,
                    apiResult.Msg,
                    JsonConvert.DeserializeObject<T>(apiResult.Data?.ToString())
                );
            }
            catch (Exception)
            {
                return ApiResult<T>.Error("Failed to parse data");
            }
        }

        #endregion

        #region 私有方法
        //----------------------------------------------------------

        /// <summary>
        /// 构建完整请求URL（自动处理路径斜杠）
        /// </summary>
        private string BuildUrl(string methodName)
        {
            // 清理方法名开头的斜杠和反斜杠
            return $"http://{url}/{methodName.TrimStart('/', '\\').Trim()}";
        }

        /// <summary>
        /// 验证方法名非空
        /// </summary>
        private void ValidateMethodName(string methodName)
        {
            if (string.IsNullOrEmpty(methodName))
                throw new Exception("功能名字不可为空");
        }

        /// <summary>
        /// 收集追踪信息和身份令牌（用于跨服务传递上下文）
        /// </summary>
        private Dictionary<HeaderName, string> GetHeader()
        {
            var headers = new Dictionary<HeaderName, string>();

            // 提取追踪ID
            if (_httpContextAccessor.HttpContext.Request.Headers
                .TryGetValue(HeaderName.trace_id.ToString(), out var traceId))
            {
                headers.Add(HeaderName.trace_id, traceId);
            }

            // 提取父Span ID（用于分布式追踪）
            if (_httpContextAccessor.HttpContext.Request.Headers
                .TryGetValue(HeaderName.pspan_id.ToString(), out var pSpanId))
            {
                headers.Add(HeaderName.pspan_id, pSpanId);
            }

            // 添加身份认证令牌
            LoginUser currentUser = _httpContextAccessor.HttpContext.GetCurrentUserInfo();
            if (currentUser != null)
            {
                headers.Add(HeaderName.auth_token, currentUser.Token);
            }

            return headers;
        }

        #endregion

        #region 未实现方法（占位符）
        //----------------------------------------------------------

        private void Publish()
        {
            // 预留的发布功能（未实现）
        }

        private void Enum(string Name)
        {
            // 预留的枚举操作（未实现）
        }

        #endregion
    }
}
